package cloud.daodao.storm.file.controller;

import cloud.daodao.storm.common.constant.AppConstant;
import cloud.daodao.storm.common.error.AppException;
import cloud.daodao.storm.common.file.constant.FileConstant;
import cloud.daodao.storm.common.file.error.FileError;
import cloud.daodao.storm.common.file.helper.FileHelper;
import cloud.daodao.storm.common.file.model.FileData;
import cloud.daodao.storm.common.file.model.FileOption;
import cloud.daodao.storm.common.file.model.FileParam;
import cloud.daodao.storm.common.model.Request;
import cloud.daodao.storm.common.model.Response;
import cloud.daodao.storm.file.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

@Tag(name = "File")
@RestController
@RequestMapping(path = AppConstant.API)
public class FileController {

    @Resource
    private FileService fileService;

    @Resource
    private FileHelper fileHelper;

    @Operation(summary = "upload 上传文件", description = "@DaoDao 使用 multipart/form-data 上传文件，key = file")
    @PostMapping(path = FileConstant.UPLOAD, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public Response<FileData> upload(
            @RequestHeader(name = AppConstant.X_HASH, required = false) String xHash,
            @RequestParam(name = "file") MultipartFile multipartFile,
            @RequestParam(name = "mark", required = false, defaultValue = "false") Boolean mark,
            @RequestParam(name = "time", required = false, defaultValue = "0") Duration time
    ) {
        FileOption option = new FileOption();
        option.setMark(mark);
        option.setTime(time);
        File file = fileHelper.transfer(multipartFile);
        fileService.checkHash(file, xHash);
        FileData data = fileService.upload(file, option);
        return new Response<>(data);
    }

    @Operation(summary = "download 下载文件", description = "@DaoDao http response 的 header 中包含文件名称， body 是文件数据流")
    @PostMapping(path = FileConstant.DOWNLOAD)
    public void download(
            @RequestBody @Valid Request<FileParam> request,
            HttpServletResponse response
    ) {
        File file = fileService.download(request.getParam());
        fileHelper.output(response, file);
    }

    @Operation(summary = "view 预览文件", description = "@DaoDao http response 的 header 中包含文件名称， body 是文件数据流")
    @GetMapping(path = FileConstant.VIEW)
    public void view(@RequestParam(name = "id") String id, @RequestParam(name = "code") String code, HttpServletResponse response) {
        FileParam param = new FileParam();
        param.setId(id);
        param.setCode(code);
        FileData data = fileService.info(param);
        if (!code.equals(data.getCode())) {
            throw new AppException(FileError.FILE_CODE_ERROR, id + " : " + code);
        }
        String name = URLEncoder.encode(data.getOrigin(), StandardCharsets.UTF_8);
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + name + "\"; filename*=utf-8' '" + name);
        File file = fileService.download(param);
        fileHelper.output(response, file);
    }

}
